home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part1 / 700 < prev    next >
Encoding:
Text File  |  1996-08-05  |  10.8 KB  |  369 lines

  1. Path: news.iag.net!news
  2. From: jatmon@iag.net (John R Buchan)
  3. Newsgroups: alt.msdos.programmer,comp.lang.c
  4. Subject: Re: Two C problems
  5. Date: 8 Jan 1996 17:16:19 GMT
  6. Organization: Internet Access Group, Orlando, Florida
  7. Distribution: world
  8. Message-ID: <4crjh3$d71@news.iag.net>
  9. References: <4cojnn$rgd@lugb.latrobe.edu.au>
  10. NNTP-Posting-Host: pm3-orl29.iag.net
  11. X-Newsreader: WinVN 0.99.7
  12.  
  13. In article <4cojnn$rgd@lugb.latrobe.edu.au>, csigjb@luxor.latrobe.edu.au 
  14. says...
  15. >
  16. >I have two C problems.
  17.  
  18. The following is a reformatted (sorry, I prefer my format) version of the 
  19. full version of the code that was originally posted (sorry about the rather 
  20. large post folks).  I have made a few modifications (I think I remembered to
  21. add comments by each.  Please excuse those that you have already corrected 
  22. in your second post) and it now seems to be functional (though I can't be 
  23. certain that it functions the way you expected).  BTW, You might want to 
  24. consider breaking your main into smaller functions.
  25.  
  26. As a few people have probably mentioned, it is considered rather poor taste
  27. to post non-ansi code in c.l.c and even worse to post incomplete uncompilable
  28. code.  Always try to post a minimum compilable example (as little non-ansi 
  29. code as possible) that illustrates your problem.  It is sometimes easier to
  30. write a new small program for this rather than trying to edit the original
  31. (just be sure that it probuces the same problem)  A consistant format and
  32. well placed comments are also helpful.
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>  /* needed for ansi exit() and EXIT_FAILURE */
  36. #include <conio.h>
  37. #include <string.h>
  38. #include <alloc.h>
  39. #include <process.h>
  40.  
  41. /* it is fairly common practice to use all caps in the names of globals. */
  42. #define  maxstring 127 /* this should be a constant expression not a const */
  43. const lineend='\n';
  44. const escape=27;
  45. const null='\0';     /* Using nul for this name will cause less confusion. */
  46. const space=' ';
  47. const up='H';
  48. const down='P';
  49. const pageup='I';
  50. const pagedown='Q';
  51. const left='K';
  52. const right='M';
  53. const home='G';
  54. const end_='O';
  55.  
  56.  
  57. typedef char string[maxstring]; /* needs a constant expression, not a const */
  58. typedef struct nodetypetag
  59.    {
  60.    string line;
  61.    int linenum;
  62.    struct nodetypetag *next,*previous;
  63.    } nodetype;
  64.  
  65. typedef nodetype *nodetypeptr;
  66.  
  67. string line,line_,line1,bottomline;
  68.  
  69. char empty(nodetypeptr posptr)
  70.    {
  71.    return(posptr==NULL);
  72.    }
  73.  
  74. void initialize(nodetypeptr *listptr)
  75.    {
  76.    *listptr=NULL;
  77.    }
  78.  
  79. void add(nodetypeptr *listptr,char *fileline,int Linenum)
  80.    {
  81.    nodetypeptr newptr,tempptr;
  82.  
  83.    newptr=(nodetypeptr)malloc(sizeof(nodetype));
  84.    /* need to verify allocation success */
  85.  
  86.    strcpy(newptr->line,fileline);
  87.    newptr->linenum=Linenum;
  88.    newptr->next=NULL;  /* no need to write this twice */
  89.    if (*listptr==NULL)
  90.       {
  91.       (*listptr)=newptr;
  92. /*      (*listptr)->next=NULL;  not needed */
  93.       (*listptr)->previous=NULL;
  94.       }
  95.    else
  96.       {
  97.       tempptr=*listptr;
  98.       while (tempptr->next!=NULL)
  99.          {
  100.          tempptr=tempptr->next;
  101.          }
  102.       tempptr->next=newptr;
  103. /*      newptr->next=NULL;   not needed */
  104.       newptr->previous=tempptr;
  105.       }
  106.    }
  107.  
  108. /* void remove(nodetypeptr *listptr) name is in conflict with the ansi */
  109. /* function remove, which is prototyped in stdio.h                     */
  110. void RemoveNode(nodetypeptr *listptr)
  111.    {
  112.    nodetypeptr tempptr;
  113.  
  114.    /* NULL tests missing */
  115.    if( listptr != NULL && *listptr != NULL) /* at least 1 node exists */
  116.       {
  117.       tempptr=*listptr;
  118.       *listptr=(*listptr)->next;
  119.       (*listptr)->previous=NULL;
  120.       free(tempptr);
  121.       }
  122.    }
  123.  
  124. /* This would probably work better as:                               *
  125. *                                                                    *
  126. *  nodetypeptr setpos( int linenum)                                  *
  127. *                                                                    *
  128. *  This would reduce the number of indirects and allow you to return *
  129. *  NULL, if an invalid number manages to be passed in.               */
  130. void setpos(nodetypeptr *posptr,int linenum)
  131.    {
  132.    while ((*posptr)->linenum!=linenum)
  133.       {
  134.       if ((*posptr)->linenum>linenum)
  135.          {
  136.          *posptr=(*posptr)->previous;
  137.          }
  138.       else
  139.          if ((*posptr)->linenum<linenum)
  140.             {
  141.             *posptr=(*posptr)->next;
  142.             }
  143.       }
  144.    }
  145.  
  146. void writescreenfull(char width,char height,nodetypeptr posptr,char stringpos)
  147.    {
  148.    char y;
  149.    char *line__;  /* this definition was apparently left out */
  150.  
  151.    window(1,1,width,height);
  152.    clrscr();
  153.    window(1,1,width,height+1);
  154.    y=1;
  155.    while ((y<=height) && (!empty(posptr->next)))
  156.       {
  157.       gotoxy(1,y);
  158.       strcpy(line_,posptr->line);
  159.       line__=&(line_[stringpos]); /* line__ = line_ + stringpos; */
  160.       strncpy(line,line__,width-1);
  161. /*      strcat(line,null); someone else explained this already */
  162.       line[maxstring - 1] = '\0'; /* this provides your safety */
  163.       cputs(line);
  164.       posptr=posptr->next;
  165.       y++;
  166.       }
  167.    }
  168.  
  169. /* Since fgets will always append a '\0', there is no need for the    *
  170.  * maxstrings parameter.  Just test for '\0' and '\n' or use the ansi *
  171.  * strrchr function.                                                  */
  172. void removelineends(char *strings,unsigned int maxstrings)
  173.    {
  174.    unsigned int i;
  175.  
  176.    i=0;
  177.    while ((i<maxstrings) && (strings[i]!=lineend))
  178.       {
  179.       i++;
  180.       }
  181.      strings[i]=null;
  182.    }
  183.  
  184. int main(int argc,char *argv[]) /* main must return int */
  185.    {
  186.    FILE *file;
  187.    char x,ch,width,height,back,fore,stringpos;
  188.    int numlines,linenum;
  189.    struct text_info info;  /* forgot the struct */
  190.    nodetypeptr listptr,posptr;
  191.  
  192.  
  193.    if (argc<2)
  194.       {
  195.       cputs("\nShow what . . .\n");
  196.       exit(EXIT_FAILURE); /* exit with failure value, when code fails */
  197.       }
  198.    else
  199.       {
  200.       file=fopen(argv[1],"rt");
  201.       if (file==NULL)
  202.          {
  203.          cprintf("\nFile %s not found . . .\n",argv[1]);
  204.          exit(EXIT_FAILURE); /* exit with failure value, when code fails */
  205.          }
  206.       else
  207.          {
  208.          rewind(file);  /* not needed, "r" opens to the beginning anyway */
  209.          initialize(&listptr);
  210.          linenum=0;
  211.          while (fgets(line,maxstring,file)!=NULL)
  212.             {
  213.             removelineends(line,maxstring);
  214.             add(&listptr,line,linenum);
  215.             linenum++;
  216.             }
  217.          numlines=linenum--;  /* ?? */
  218.          fclose(file);
  219.  
  220.          posptr=listptr;
  221.  
  222. /* This would make a nice 'InitScreen' function */
  223.          gettextinfo(&info);
  224.          fore=info.attribute&0x0f;
  225.          back=(info.attribute&0x70)/0x10;
  226.          height=info.screenheight;
  227.          width=info.screenwidth;
  228.          strcpy(bottomline,"  \30  \31  pgup  pgdn  s <string> "
  229.                            "(search for string)  esc (quit)");
  230.          for(x=strlen(bottomline)+1;x<width;x++)
  231.             {
  232.             strcat(bottomline," ");
  233.             }
  234.          /* look into sprintf */
  235.  
  236.          _setcursortype(_NOCURSOR);
  237.          clrscr();
  238.          textcolor(back);
  239.          textbackground(fore);
  240.          gotoxy(1,height);
  241.          cputs(bottomline);
  242.          textcolor(fore);
  243.          textbackground(back);
  244. /* end 'InitScreen' function */
  245.  
  246.          height--;
  247.          linenum=0;   /* the first line in your list is 0, not 1 */
  248.          stringpos=0; /* this should start at 0, not 1 */
  249.          writescreenfull(width,height,posptr,stringpos);
  250.          ch=space;
  251.          while (ch!=escape)
  252.             {
  253.             while ((ch!=up) && (ch!=down) && (ch!=pageup) &&
  254.                        (ch!=pagedown) && (ch!=escape) && (ch!=left) &&
  255.                                (ch!=right) && (ch!=end_) && (ch!=home))
  256.                {
  257.                ch=getch();
  258.                if (ch==null)
  259.                   {
  260.                   ch=getch();
  261.                   }
  262.                }
  263.  
  264. /* This would be much clearer using a switch statement */
  265.             if (ch==up)
  266.                {
  267.                if ((linenum-1)>=0)
  268.                   {
  269.                   linenum--;
  270.                   }
  271.                else
  272.                   {
  273.                   linenum=0;
  274.                   }
  275.                setpos(&posptr,linenum);
  276.                }
  277.             else
  278.                if (ch==down)
  279.                   {
  280.                   if ((linenum+1+height)<=numlines) /* ?? */
  281.                      {
  282.                      linenum++;
  283.                      }
  284.                   else
  285.                      {
  286.                      linenum=numlines-height+1;
  287.                      }
  288.                  setpos(&posptr,linenum);
  289.                  }
  290.               else
  291.                  if (ch==pageup)
  292.                     {
  293.                     if ((linenum-height+1)>=1)
  294.                        {
  295.                        linenum=linenum-height+1;
  296.                        }
  297.                     else
  298.                        {
  299.                        linenum=1;
  300.                        }
  301.                     setpos(&posptr,linenum);
  302.                     }
  303.                  else
  304.                     if (ch==pagedown)
  305.                        {
  306.                        if (((linenum+height-1)<=numlines) &&
  307.                              ((numlines-(linenum+height-1))>=(height-1)))
  308.                           {
  309.                           linenum=linenum+height-1;
  310.                           }
  311.                        else
  312.                           {
  313.                           linenum=numlines-height+1;
  314.                           }
  315.                        setpos(&posptr,linenum);
  316.                        }
  317.                     else
  318.                        if (ch==left)
  319.                           {
  320.                           if (stringpos>0) /* s/b 0 */
  321.                              {
  322.                              stringpos--;
  323.                              }
  324.                           }
  325.                        else
  326.                           if (ch==right)
  327.                              {
  328.                              if (stringpos<=(maxstring-width))
  329.                                 {
  330.                                 stringpos++;
  331.                                 }
  332.                              }
  333.                           else
  334.                              if (ch==end_)
  335.                                 {
  336.                                 stringpos=maxstring-width+1;
  337.                                 }
  338.                              else
  339.                                 if (ch==home)
  340.                                    {
  341.                                    stringpos=0; /* s/b 0, not 1 */
  342.                                    }
  343.             if (ch!=escape)
  344.                {
  345.                ch=space;
  346.                }
  347.             writescreenfull(width,height,posptr,stringpos);
  348.             }
  349.          height+=1;
  350.          window(1,1,width,height);
  351.          clrscr();
  352.          _setcursortype(_NORMALCURSOR);
  353.          while (!empty(listptr))
  354.             {
  355.             RemoveNode(&listptr);
  356.             }
  357.          }
  358.       }
  359.    
  360.    return 0;
  361.    }
  362.  
  363.  
  364.  
  365. -- 
  366. John R Buchan           -:|:-     Looking for that elusive FAQ?  ftp to:
  367. jatmon@mail.iag.net     -:|:-     rtfm.mit.edu /pub/usenet-by-group/....
  368.  
  369.